package com.itheima.springbootsecurity.handler;

import com.alibaba.fastjson2.JSON;
import com.itheima.springbootsecurity.domain.Result;
import com.itheima.springbootsecurity.exception.CustomAuthenticationException;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 匿名用户访问无权限资源时的处理器
 * 客户端进行登录时出现异常，或者匿名用户访问受限资源的处理器
 *
 * @author wuhaohua
 */
@Component
public class AnonymousAuthenticationHandler implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        // 设置客户端的响应的内容类型
        response.setContentType("application/json;charset=UTF-8");
        // 获取输出流
        ServletOutputStream outputStream = response.getOutputStream();

        String resultJson = null;

        System.out.println(authException.getMessage() + "===" + authException);

        if (authException instanceof BadCredentialsException) {
            // 用户名密码认证失败异常
            resultJson = JSON.toJSONString(Result.error("用户名或密码错误"));
        } else if (authException instanceof InternalAuthenticationServiceException) {
            // 不存在正在登录的用户的异常
            resultJson = JSON.toJSONString(Result.error("用户名为空"));
        } else if (authException instanceof CustomAuthenticationException || authException instanceof Exception) {
            // 代码中抛出的异常
            resultJson = JSON.toJSONString(Result.error(authException.getMessage()));
        } else {
            // 其他身份验证异常
            resultJson = JSON.toJSONString(Result.error("系统内部错误，请联系管理员"));
        }

        // 将json对象写到输出流中
        outputStream.write(resultJson.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }
}
